﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using EntitiesLayer;
using BusinessLayer;
using DataLayer;
using Bitacora;

namespace BatchImporterServiceToDB
{
    public partial class BatchImporterServiceToDB : ServiceBase
    {
        public BatchImporterServiceToDB()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns>True si la configuracion dada en los parametros es correcta.</returns>
        private bool VerificarConfiguracion()
        {
            #region Parameters not null

            if (Configuracion.minutosRetraso <= 0)
            {
                Services.EnviarLog("Unisys Batch Importer To DB", 51, "El parametro delay debe ser mayor a cero", "Verifyconfiguration", Bitacora.TipoError.Error);
                return false;
            }

            if (Configuracion.horarioEjecucion.Equals(""))
            {
                Services.EnviarLog("Unisys Batch Importer To DB", 52, "El parametro schedulesTimes no puede estar en blanco", "Verifyconfiguration", Bitacora.TipoError.Error);
                return false;
            }

            if (Configuracion.identificacionSistema.Equals(""))
            {
                Services.EnviarLog("Unisys Batch Importer To DB", 54, "El parametro systemID no puede estar en blanco", "Verifyconfiguration", Bitacora.TipoError.Error);
                return false;
            }


            #endregion

            if (!(this.VerificarBaseDatos()))
                return false;

            return true;

        }

        /// <summary>
        /// Verifica que la configuración de conexion a la Base de Datos sea correcta.
        /// </summary>
        /// <returns>True, si la configuracion con la Base de Datos es correcta.</returns>
        private bool VerificarBaseDatos()
        {
            try
            {
                Services.EnviarLog("Unisys Batch Importer To DB", 523, "Intentando Conectarse a la base de datos", "VerificarBaseDatos", Bitacora.TipoError.Informacion);
                SqlDataClass.ProbarConnection(true);
                SqlDataClass.ProbarConnection(false);
                Services.EnviarLog("Unisys Batch Importer To DB", 262, "Seccion de BD ok", "VerificarBaseDatos", Bitacora.TipoError.Informacion);
                return true;
            }
            catch (Exception e)
            {
                Services.EnviarLog("Unisys Batch Importer To DB",152, "Imposible conectar con la Base de Datos", "VerificarBaseDatos", Bitacora.TipoError.Error,e);
                return false;
            }
        }

        protected override void OnStart(string[] args)
        {
           //System.Diagnostics.Debugger.Launch();

            #region Load Configuration
            try
            {
              
                if (!(this.VerificarConfiguracion()))
                {
                    Logger.LogEnWindows("Error al intentar leer la configuración de la aplicación. La verificación de la configuración" +
                    " no ha finalizado con éxito, favor revise la configuración", "Unisys Batch Importer Services", "Unisys Batch Importer Services");
                    System.Environment.Exit(0);
                }
            }
            catch (Exception e)
            {
                Logger.LogEnWindows("Error al intentar leer la configuracion de la aplicacion " + e.Message, "Unisys Batch Importer Services", "Unisys Batch Importer Services");
                System.Environment.Exit(0);
            }

            Services.EnviarLog("Unisys Batch Importer To DB", 251, "El servicio Unisys Batch Importer To DB ha levantado su configuración correctamente.", "OnStart", Bitacora.TipoError.Log);


            Services.EnviarLog("Unisys Batch Importer To DB", 252, "Configuración cargada correctamente con los siguientes valores:" +
                 "\n Ubicación de Logs: [" + Configuracion.ubicacionLogs +
                "]\n Ruta Archivos Data: [" + Configuracion.rutaArchivosData +
                "]\n Ruta Archivos Imagen: " + "[" + Configuracion.rutaImagenes +
                "]\n Ruta Archivos Data No Cargados: " + "[" + Configuracion.rutaArchivosNoCargados +
                "]\n Ruta Archivos Data Cargados: " + "[" + Configuracion.rutaArchivosCargados +
                "]\n Archivo Parámetros Cheques: [" + Configuracion.archivoParametrosCheques +
                //"]\n categoriesWithoutImages: " + "[" + Configuration.categoriesWithoutImages +
                "] \n Identificación del Sistema: [" + Configuracion.identificacionSistema +
                "]",
                "OnStart", Bitacora.TipoError.Informacion);

            #endregion

            this.backgroundWorker1.RunWorkerAsync();

        }

        protected override void OnStop()
        {
            BatchImporterProcesses.toProcess = false;
            this.backgroundWorker1.CancelAsync();
            Services.EnviarLog("Unisys Batch Importer To DB", 263, "*******        Unisys Batch Importer To DB detenido correctamente       *******", "OnStop", Bitacora.TipoError.Log);
        }

        private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            backgroundWorker1.WorkerSupportsCancellation = true;

            while (!backgroundWorker1.CancellationPending)
            {
                if (DiaEjecucion())
                {
                    Services.EnviarLog("Unisys Batch Importer To DB", 264, "*********        Unisys Batch Importer To DB iniciado correctamente      ********", "BackgroundWorker1_DoWork", Bitacora.TipoError.Log);
                    Services.EnviarLog("Unisys Batch Importer To DB", 524, "Ciclo de proceso activado, buscando archivos pendientes de procesar...", "BackgroundWorker1_DoWork", Bitacora.TipoError.Log);
                    BatchImporterProcesses.CargarDataBaseDatos();
                    Services.EnviarLog("Unisys Batch Importer To DB", 525, "Ciclo de proceso concluido y desactivado.", "BackgroundWorker1_DoWork", Bitacora.TipoError.Log);
                }
                else
                {
                    Services.EnviarLog("Unisys Batch Importer To DB", 265, "*********        Unisys Batch Importer to DB pausado correctamente      ********", "BackgroundWorker1_DoWork", Bitacora.TipoError.Log);
                }
                int tiempoDelay = CalcularDelay();
                int tiempoDelayMinutos = tiempoDelay / 60000;
                Services.EnviarLog("Unisys Batch Importer To DB",526, "Próximo ciclo dará inicio en " + tiempoDelayMinutos + " minutos.", "BackgroundWorker1_DoWork", Bitacora.TipoError.Log);
                System.Threading.Thread.Sleep(tiempoDelay);
            }

        }

        /// <summary>
        /// Verifica que al momento de ejecución del servicio
        /// el dia se encuentre dentro de los configurados para que de inicio el
        /// procesamiento.
        /// </summary>
        /// <returns>True, si el dia actual se encuentra configurado.</returns>
        private bool DiaEjecucion()
        {
            string[] days = Configuracion.horarioEjecucion[0].ToString().Split(',');


            //Check Day
            string dia = "";
            for (int i = 0; i < days.Length;i++)
            {
                switch (days[i])
                {
                    case "L": dia = "Monday"; break;
                    case "K": dia = "Tuesday"; break;
                    case "M": dia = "Wednesday"; break;
                    case "J": dia = "Thursday"; break;
                    case "V": dia = "Friday"; break;
                    case "S": dia = "Saturday"; break;
                    case "D": dia = "Sunday"; break;
                }

                if (dia.Equals(DateTime.Now.DayOfWeek.ToString()))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Calcula la cantidad de minutos restantes para iniciar un nuevo ciclo de ejecución de aceurdo a la 
        /// configuracion proporcionada.
        /// </summary>
        /// <returns>Cantidad de Minutos restantes para la siguiente ejecución.</returns>
        private int CalcularDelay()
        {
            int horaInicio = Int32.Parse(Configuracion.horarioEjecucion[1]);
            int horaFin = Int32.Parse(Configuracion.horarioEjecucion[2]);
            int horaActual = Int32.Parse(DateTime.Now.ToString("HHmm")); 

            if ((horaInicio < horaActual) && (horaActual < horaFin) && DiaEjecucion())
            {
                return 60000 * Configuracion.minutosRetraso;
            }
            else
            {
                int minutosRestantesHoy = 60000*((24-DateTime.Now.Hour)*60-DateTime.Now.Minute);
                int minutosRestantesManana = 60000*((Int32.Parse(Configuracion.horarioEjecucion[1].Substring(0,2))*60)+
                                                Int32.Parse(Configuracion.horarioEjecucion[1].Substring(2,2)));
                int total = minutosRestantesHoy + minutosRestantesManana;
                return total;
            }


        }




    }
}
